<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="spec/resources/custom-elements-helpers.js"></script>
<body>
<script>
'use strict';

setup({
  allow_uncaught_exception: true,
});

test_with_window((w) => {
  let doc = w.document;
  let e = doc.createElement('a-a');
  doc.body.appendChild(e);
  var misbehave = true;
  var invocations = [];
  class X extends w.HTMLElement {
    constructor() {
      if (misbehave) {
        misbehave = false;
        invocations.push('misbehaving');
        return new X();
      }
      super();
      invocations.push(this);
    }
  }
  w.customElements.define('a-a', X);
  assert_array_equals(invocations, ['misbehaving', e],
                      'returning the existing element should have succeeded');
}, 'HTMLElement constructor: poach but return upgrade candidate');

test_with_window((w) => {
  let doc = w.document;
  let e = doc.createElement('a-a');
  doc.body.appendChild(e);
  var misbehave = true;
  var invocations = [];
  var poacher;
  class X extends w.HTMLElement {
    constructor() {
      if (misbehave) {
        misbehave = false;
        poacher = new X();
      }
      try {
        super();
        invocations.push(this);
      } catch (e) {
        invocations.push(e);
      }
    }
  }
  w.customElements.define('a-a', X);
  assert_equals(invocations.length, 2,
                'the constructor should have been invoked once for upgrade ' +
                'and once for the recursive call to "new"');
  assert_equals(poacher, e,
                'the recursive "new" should steal the upgrade candidate');
  assert_equals(poacher, invocations[0],
                'the recursize "new" should happen first');
  assert_true(invocations[1] instanceof w.TypeError,
              'the super call should have thrown a TypeError');
}, 'HTMLElement constructor: poach upgrade candidate');
</script>
